package com.example.model.response;

import com.example.enums.ErrorCode;

import java.lang.reflect.Array;
import java.util.Collection;
import java.util.Map;

/**
 * 统一响应实体构建类
 */
public class RestResponseEntity {

    /**
     * 创建一个Http请求的返回结果对象（成功/失败 通用）
     *
     * @param code        请求代码 没有错误则为0
     * @param description 请求结果描述
     * @param data        数据,数量为0时,可以为null
     * @param extra       额外的数据,主要用于分页查询,返回的总页数,可以为null
     * @return 结果对象
     */
    private static <T> RestResponse<T> newResponse(Integer code, String description, T data, Object extra) {
        RestResponse<T> response = new RestResponse<>();
        return response.setErrorCode(code)
                .setDescription(description)
                .setData(data)
                .setDataSize(getDataSize(data))
                .setExtra(extra);
    }

    /**
     * 创建一个Http请求 操作成功 的返回结果对象（成功代码，有数据，有描述，有额外信息）
     *
     * @param description 请求结果描述
     * @param data        数据
     * @param extra       额外的数据,主要用于分页查询,返回的总页数,可以为null
     * @return 结果对象
     */
    public static <T> RestResponse<T> newSuccessResponse(String description, T data, Object extra) {
        return newResponse(ErrorCode.SUCCESS.getCode(), description, data, extra);
    }

    /**
     * 创建一个操作失败的返回结果对象（有错误代码，有描述，有数据，没有额外信息）
     *
     * @param description 请求结果描述
     * @param errorCode   错误代码
     * @param data        数据
     * @return 结果对象
     */
    public static <T> RestResponse<T> newFailResponse(ErrorCode errorCode, String description, T data) {
        return newResponse(errorCode.getCode(), description, data, null);
    }

    /**
     * 创建一个操作失败的返回结果对象（有错误代码，有描述，没有数据，没有额外描述）
     *
     * @param errorCode   错误代码
     * @param description 请求结果描述
     * @return 结果对象
     */
    public static <T> RestResponse<T> newFailResponse(ErrorCode errorCode, String description) {
        return newResponse(errorCode.getCode(), description, null, null);
    }


    public static <T> RestResponse<T> newResponseFromServiceResult(ServiceResult<T> serviceResult) {
        // 如果执行成功，就返回前端 操作成功 的结果对象
        if (serviceResult.isSuccess()) {
            return newSuccessResponse(serviceResult.getDescription(), serviceResult.getData(), serviceResult.getExtra());
        } else {
            // 执行失败，就返回前端 操作失败 的结果对象
            return newFailResponse(serviceResult.getErrorCode(), serviceResult.getDescription(), serviceResult.getData());
        }
    }

    /**
     * 计算数据大小
     * 该方法用于下载进度条的显示
     *
     * @param data 数据：数据，集合，map都支持
     * @return 数据大小
     */
    private static <T> int getDataSize(T data) {
        if (data == null)
            return 0;
        if (data.getClass().isArray())
            return Array.getLength(data);
        if (data instanceof Collection<?>)
            return ((Collection<?>) data).size();
        if (data instanceof Map<?, ?>)
            return ((Map<?, ?>) data).size();
        return 1;
    }
}
